package com.xtayfjpk.security;

import java.security.Key;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

import org.junit.Test;

/**
 * PBE Password Based Encryption
 * @author zj
 *
 */
public class PBETest {
	/**
	 * Java6 支持以下任意一种算法
	 * PBEwithMD5andDES
	 * PBEwithMD5andTripleDES
	 * PBEwithSHA1andDESede
	 * PBEwithSHA1andRC2_40
	 * PBKDF2withHmacSHA1
	 */
	public static final String ALGORITHM = "PBEWITHMD5ANDDES";
	
	/**
	 * 迭代次数
	 */
	public static final int INTERATION_COUNT = 100;
	
	public static byte[] initSalt() throws Exception {
		SecureRandom random = new SecureRandom();
		return random.generateSeed(8);
	}
	
	public static Key toKey(String password) throws Exception {
		PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
		SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);
		return factory.generateSecret(keySpec);
	}
	
	public static byte[] encrytp(byte[] data, String password, byte[] salt) throws Exception {
		Key key = toKey(password);
		PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, INTERATION_COUNT);
		Cipher cipher = Cipher.getInstance(ALGORITHM);
		cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
		return cipher.doFinal(data);
	}
	
	public static byte[] decrypt(byte[] data, String password, byte[] salt) throws Exception {
		Key key = toKey(password);
		Cipher cipher = Cipher.getInstance(ALGORITHM);
		PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, INTERATION_COUNT);
		cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);
		return cipher.doFinal(data);
	}
	
	@Test
	public void test() throws Exception {
		String inputString = "PBE";
		String password = "xtayfjpk";
		
		byte[] salt = initSalt();
		byte[] ciphered = encrytp(inputString.getBytes(), password, salt);
		
		byte[] deciphered = decrypt(ciphered, password, salt);
		
		System.out.println(new String(deciphered));
	}
}
